
package petrivis.view;

import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import petrivis.model.PetriNet;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.layout.graph.NodeLinkTreeLayout;
import prefuse.activity.Activity;
import prefuse.data.expression.Predicate;
import prefuse.data.expression.parser.ExpressionParser;
import prefuse.visual.expression.InGroupPredicate;

/**
 * The Visualization of the Petri Net
 * @author Jorge Munoz
 */
public class PNVisualization extends Visualization implements Serializable{

    /** Graph Elements Group Name */
    public static final String GRAPH = "petrinet";
    /** Nodes Group Name */
    public static final String NODES = "petrinet.nodes";
    /** Edges Group Name */
    public static final String EDGES = "petrinet.edges";
    /** Tokens Group Name */
    public static final String TOKENS= "tokens";
    /** Weights Group Name */
    public static final String WEIGHTS= "weights";

    //Disable the Predicate Info Warnings
    static{
        Logger.getLogger("prefuse.data.expression.parser").setLevel(Level.OFF);
    }

    /** Text of the Place Predicate */
    public static String placePredTxt = "ISNODE() AND ["+PetriNet.PLACE_COL+"]==true";
    /** Place Predicate*/
    public static Predicate placePred = ExpressionParser.predicate(placePredTxt);
    /** Text of the Transition Predicate */
    public static String transPredTxt = "ISNODE() AND ["+PetriNet.PLACE_COL+"]==false";
    /** Transition Predicate*/
    public static Predicate transPred = ExpressionParser.predicate(transPredTxt);
    /** Text of the Arc Predicate */
    public static String arcPredTxt = "ISEDGE()";
    /** Arc Predicate*/
    public static Predicate arcPred = ExpressionParser.predicate(arcPredTxt);


    /** Tokens Group Predicate*/
    public static Predicate tokensGroupPred = new InGroupPredicate(TOKENS);

    /** Text of Weight Edge Predicate */
    public static String weightPredTxt = arcPredTxt+" AND ["+PetriNet.WEIGHT_COL+"] > 1";
    /** Weight Edge Predicate*/
    public static Predicate weightPred = ExpressionParser.predicate(weightPredTxt);
    /** Weight Group Predicate*/
    public static Predicate weightGroupPred = new InGroupPredicate(WEIGHTS);


    public PNVisualization(PetriNet pN){

        //Mapping of source data to a visual abstraction in groups
        addGraph(GRAPH,pN);


        //DECORATORS
        this.addDecorators(TOKENS, NODES, placePred);
        this.addDecorators(WEIGHTS, EDGES, weightPred);


        //RENDERERS
        PNRendererFactory rendererFact = new PNRendererFactory();
        setRendererFactory(rendererFact);

        
        //ACTIONS
        //Draw
        ActionList draw = new ActionList();
        draw.add(new PNColorActionList());
        //draw.add(new RepaintAction());
        putAction("draw", draw);

        //Layout
        ActionList layout = new ActionList();
        layout.add(new NodeLinkTreeLayout(GRAPH));
        layout.add(new RepaintAction());
        putAction("layout", layout);
        
        //ZoomToFit
        ZoomToFitAction zoomToFit = new ZoomToFitAction(this);
        putAction("zoomtofit", zoomToFit);

        //Decorators
        ActionList decorators = new ActionList(Activity.INFINITY);
        decorators.add(new CenterDecoratorsAction(WEIGHTS));
        putAction("decorators", decorators);

        this.runAfter("draw", "layout");
        this.runAfter("layout", "decorators");
        this.runAfter("layout", "zoomtofit");


    }

}
